package cn.tedu.lucky.draw.server.service.impl;

import cn.tedu.lucky.draw.server.common.enums.DrawEnum;
import cn.tedu.lucky.draw.server.common.enums.ErrorEnum;
import cn.tedu.lucky.draw.server.common.handler.DrawException;
import cn.tedu.lucky.draw.server.protocol.po.ActivityRule;
import cn.tedu.lucky.draw.server.protocol.po.Rule;
import cn.tedu.lucky.draw.server.protocol.query.RuleQuery;
import cn.tedu.lucky.draw.server.repository.ActivityRuleRepository;
import cn.tedu.lucky.draw.server.repository.RuleRepository;
import cn.tedu.lucky.draw.server.service.IRuleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class RuleServiceImpl implements IRuleService {

    @Autowired
    private RuleRepository ruleRepository;

    @Autowired
    private ActivityRuleRepository activityRuleRepository;

    List<Rule> ruleList;

    @Override
    public List<Rule> findAll(RuleQuery ruleQuery) {

        if (ruleList == null) {
            ruleList = ruleRepository.findAll();
        }

        String name = ruleQuery.getName();
        Integer status = ruleQuery.getStatus();
        return ruleList.stream()
                .filter(rule -> name == null || name == "" || rule.getName().equals(name))
                .filter(rule -> status == null || status.equals(rule.getStatus()))
                .collect(Collectors.toList());
    }

    @Override
    public void save(Rule rule) {
        LocalDateTime now = LocalDateTime.now();
        rule.setCreateTime(now);
        rule.setUpdateTime(now);
        Rule save = ruleRepository.save(rule);
        if (save == null) {
            throw new DrawException(ErrorEnum.SYSTEM_ERROR);
        }
        ruleList = null;
    }

    @Override
    public List<Rule> findRulesByActivityId(Long activityId) {
        List<ActivityRule> activityRules = activityRuleRepository.findByActivityId(activityId);
        List<Long> ruleIds = activityRules.stream().map(ActivityRule::getRuleId).collect(Collectors.toList());
        return ruleRepository.findAllById(ruleIds);
    }

    @Override
    public List<Rule> findNoBindRuleByActivityId(Long activityId) {
        List<ActivityRule> activityRules = activityRuleRepository.findByActivityId(activityId);
        List<Long> excludedIds = activityRules.stream().map(ActivityRule::getRuleId).collect(Collectors.toList());
        Integer status = Integer.valueOf(DrawEnum.ENABLE.getCode());
        if (excludedIds==null || excludedIds.isEmpty()){
            return ruleRepository.findByStatus(status);
        }
        return ruleRepository.findByStatusAndIdNotIn(status, excludedIds);
    }
}
